#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

using namespace std;

int udp_send(const char *host, const char *service, const char *message)
{
    int sockfd, ret;
    struct addrinfo hints, *res, *ressave;
    socklen_t len;
    ssize_t n;

    bzero(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM; // 修改为UDP
    hints.ai_protocol = IPPROTO_UDP;

    if (0 != (ret = getaddrinfo(host, service, &hints, &res)))
    {
        cout << "getaddrinfo error: " << gai_strerror(ret) << endl;
        return -1;
    }

    ressave = res;
    sockfd = -1;
    while (NULL != res)
    {
        printf("%d %d %d==\n",res->ai_family, res->ai_socktype, res->ai_protocol);
        sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); //socket(res->ai_family, res->ai_socktype, res->ai_protocol)
        if (sockfd >= 0)
            break; // 成功创建socket就跳出循环
        res = res->ai_next;
    }

    if (sockfd < 0)
    {
        cout << "create socket error: " << strerror(errno) << endl;
        freeaddrinfo(ressave);
        return -1;
    }
     for (size_t i = 0; i < 14; i++)
     {
       printf("%.2x ",res->ai_addr->sa_family);
     }
     
    // 直接发送数据，无需connect
    n = sendto(sockfd, message, strlen(message), 0, res->ai_addr, res->ai_addrlen);
    if (n < 0)
    {
        cout << "sendto error: " << strerror(errno) << endl;
    }
    else
    {
        cout << "Sent message: " << message << endl;
    }

    freeaddrinfo(ressave);
    close(sockfd);

    return n;
}

int main(int argc, char *argv[])
{
    if (4 != argc)
    {
        cout << "usage: " << argv[0] << " <hostname/ipaddress> <service/port> <message_to_send>" << endl;
        return -1;
    }

    int result = udp_send(argv[1], argv[2], argv[3]);
    if (result < 0)
    {
        cout << "Error sending UDP message" << endl;
        return -1;
    }

    return 0;
}